package com.zenithmind.note.pojo.entity;

import com.zenithmind.common.base.BaseEntity;
import com.zenithmind.note.pojo.enums.CommentStatus;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

/**
 * 笔记评论实体类
 * 遵循面向对象设计原则：
 * 1. 单一职责：只负责评论数据和评论相关业务逻辑
 * 2. 封装性：提供业务方法控制评论状态变更
 * 3. 数据完整性：确保评论的基本信息完整
 */
@EqualsAndHashCode(callSuper = true)
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Schema(name = "笔记评论实体", description = "笔记评论实体")
public class NoteComment extends BaseEntity {

    @Schema(description = "笔记ID")
    @NotNull(message = "笔记ID不能为空")
    private String noteId;

    @Schema(description = "评论用户ID")
    @NotNull(message = "用户ID不能为空")
    private String userId;

    @Schema(description = "父评论ID，用于回复功能")
    private String parentId;

    @Schema(description = "评论内容")
    @NotBlank(message = "评论内容不能为空")
    @Size(max = 1000, message = "评论内容不能超过1000个字符")
    private String content;

    @Schema(description = "点赞数")
    private Integer likeCount;

    @Schema(description = "评论状态")
    private Integer status;

    // ==================== 业务方法 ====================

    /**
     * 获取评论状态枚举
     *
     * @return 评论状态
     */
    public CommentStatus getCommentStatus() {
        return CommentStatus.fromCode(this.status);
    }

    /**
     * 设置评论状态
     *
     * @param commentStatus 评论状态
     */
    public void setCommentStatus(CommentStatus commentStatus) {
        this.status = commentStatus != null ? commentStatus.getCode() : null;
    }

    /**
     * 判断是否为根评论（非回复）
     *
     * @return 是否为根评论
     */
    public boolean isRootComment() {
        return this.parentId == null || this.parentId.trim().isEmpty();
    }

    /**
     * 判断是否为回复评论
     *
     * @return 是否为回复评论
     */
    public boolean isReplyComment() {
        return !isRootComment();
    }

    /**
     * 判断是否可以被显示
     *
     * @return 是否可显示
     */
    public boolean isVisible() {
        CommentStatus commentStatus = getCommentStatus();
        return commentStatus != null && commentStatus.isVisible();
    }

    /**
     * 判断是否可以被编辑
     *
     * @param currentUserId 当前用户ID
     * @return 是否可编辑
     */
    public boolean isEditableBy(String currentUserId) {
        if (currentUserId == null || !currentUserId.equals(this.userId)) {
            return false;
        }

        CommentStatus commentStatus = getCommentStatus();
        return commentStatus != null && commentStatus.isEditable();
    }

    /**
     * 判断是否可以被删除
     *
     * @param currentUserId 当前用户ID
     * @return 是否可删除
     */
    public boolean isDeletableBy(String currentUserId) {
        if (currentUserId == null || !currentUserId.equals(this.userId)) {
            return false;
        }

        CommentStatus commentStatus = getCommentStatus();
        return commentStatus != CommentStatus.DELETED;
    }

    /**
     * 审核通过评论
     */
    public void approve() {
        setCommentStatus(CommentStatus.VALID);
    }

    /**
     * 删除评论（软删除）
     */
    public void delete() {
        setCommentStatus(CommentStatus.DELETED);
    }

    /**
     * 设置为审核中状态
     */
    public void setReviewing() {
        setCommentStatus(CommentStatus.REVIEWING);
    }

    /**
     * 增加点赞数
     *
     * @param increment 增量（可以为负数表示取消点赞）
     */
    public void incrementLikeCount(int increment) {
        if (this.likeCount == null) {
            this.likeCount = 0;
        }
        this.likeCount = Math.max(0, this.likeCount + increment);
    }

    /**
     * 初始化新评论的默认值
     */
    public void initializeDefaults() {
        if (this.likeCount == null) {
            this.likeCount = 0;
        }
        if (this.status == null) {
            setCommentStatus(CommentStatus.VALID);
        }
    }

    /**
     * 验证评论内容是否合法
     *
     * @return 是否合法
     */
    public boolean isContentValid() {
        return this.content != null &&
               !this.content.trim().isEmpty() &&
               this.content.length() <= 1000;
    }
}